package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.ServiceItemMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 养修服务项Service业务层处理
 * 
 * @author wolfcode
 * @date 2021-05-14
 */
@Service
public class ServiceItemServiceImpl implements IServiceItemService
{
    @Autowired
    private ServiceItemMapper serviceItemMapper;

    @Autowired
    private IProcessService processService;

    @Autowired
    private ICarPackageAuditService carPackageAuditService;

    @Autowired
    private IDefinitionNodeService definitionNodeService;
    /**
     * 查询养修服务项
     * 
     * @param id 养修服务项ID
     * @return 养修服务项
     */
    @Override
    public ServiceItem selectServiceItemById(Long id)
    {
        return serviceItemMapper.selectServiceItemById(id);
    }

    /**
     * 查询养修服务项列表
     * 
     * @param serviceItem 养修服务项
     * @return 养修服务项
     */
    @Override
    public List<ServiceItem> selectServiceItemList(ServiceItem serviceItem)
    {
        return serviceItemMapper.selectServiceItemList(serviceItem);
    }

    /**
     * 新增养修服务项
     * 
     * @param serviceItem 养修服务项
     * @return 结果
     */
    @Override
    public int insertServiceItem(ServiceItem serviceItem)
    {
        serviceItem.setCreateTime(DateUtils.getNowDate());
        if(ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);//设置初始化
        }
        return serviceItemMapper.insertServiceItem(serviceItem);
    }

    /**
     * 修改养修服务项
     * 
     * @param serviceItem 养修服务项
     * @return 结果
     */
    @Override
    public int updateServiceItem(ServiceItem serviceItem)
    {
        ServiceItem oldObj = serviceItemMapper.selectServiceItemById(serviceItem.getId());
        //处于上架状态的商品不能修改
        if(ServiceItem.SALESTATUS_ON.equals(oldObj.getSaleStatus())){
            throw new BusinessException("上架服务项目不能修改，请下架后再修改");
        }else if(ServiceItem.AUDITSTATUS_AUDITING.equals(oldObj.getAuditStatus())){
            throw new BusinessException("服务项目正在审核中,不可修改");
        }
        //如果是审核通过，此时修改，需要将其状态变更为初始化
        if(ServiceItem.AUDITSTATUS_APPROVED.equals(oldObj.getAuditStatus())){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }
        serviceItem.setVersion(oldObj.getVersion());
        return serviceItemMapper.updateServiceItem(serviceItem);
    }
    /**
     * 删除养修服务项对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteServiceItemByIds(String ids)
    {
        return serviceItemMapper.deleteServiceItemByIds(Convert.toStrArray(ids));
    }
    /**
     * 下架
     *
     * @param id 需要下架的服务项ID
     * @return .
     */
    @Override
    public int saleOff(Long id) {
        return serviceItemMapper.changeSaleStatus(id,ServiceItem.SALESTATUS_OFF);
    }
    /**
     * 上架
     * @param id 需要上架的服务ID
     * @return .
     */
    @Override
    public int saleOn(Long id) {
        ServiceItem serviceItem = selectServiceItemById(id);
        //如果不是套餐，可以直接上架
        //如果是套餐，只有审核成功才能上架
        if(ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
                && !ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())){
            throw new BusinessException("套餐服务项需要审核通过之后才能上架");
        }
        return serviceItemMapper.changeSaleStatus(id,ServiceItem.SALESTATUS_ON);
    }
    /**
     * 查询上家的养修服务项列表
     *
     * @param serviceItem 养修服务项
     * @return 养修服务项集合
     */
    @Override
    public List<ServiceItem> selectAllSaleOnList(ServiceItem serviceItem) {
        return serviceItemMapper.selectAllSaleOnList(serviceItem);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void startAudit(Long id) {
    //发起审核流程:
        // 1.生成审核记录
        CarPackageAudit carPackageAudit = new CarPackageAudit();
        //1.1设置创建人为当前用户
        SysUser sysUser = ShiroUtils.getSysUser();//获取当前用户
        carPackageAudit.setCreateBy(String.valueOf(sysUser.getUserId()));//设置创建人Id
        carPackageAudit.setCreateByName(sysUser.getUserName());//设置创建人名字
        //1.2获取到服务项信息对象，将其转换为json字符串，将字符串设置到审核记录中
        ServiceItem serviceItem = this.selectServiceItemById(id);

        if (ServiceItem.CARPACKAGE_NO.equals(serviceItem.getCarPackage())){
            throw  new BusinessException("只有套餐才能发起审核");
        }
        //判断当前状态是否为初始化状态
        if (!ServiceItem.AUDITSTATUS_INIT.equals(serviceItem.getAuditStatus())){
            throw new BusinessException("必须是初始化状态才能审核");
        }
        //将服务项状态改为审核中
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_AUDITING);
        serviceItemMapper.updateServiceItem(serviceItem);
        carPackageAudit.setServiceItemInfo(JSON.toJSONString(serviceItem));
        // 1.3状态设置为进行中
        carPackageAudit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        //1.4将审核记录保存到数据库
        carPackageAuditService.insertCarPackageAudit(carPackageAudit);//得到自增的Id作为业务key
        //2.开始activiti审核流程(businessKey/流程参数)
        // 2.1创建流程变量对象Map
        HashMap<String, Object> map = new HashMap<>();
        map.put("money", serviceItem.getDiscountPrice().doubleValue());
        //2.2使用运行时Service开启审核（流程定义key，businessKey=审核记录id，流程变量) ,返回流程实例对象
        String businessKey = String.valueOf(carPackageAudit.getId());//自增的Id作为流程的业务key
        String definitionKey = CarPackageAudit.DEFINITION_KEY;
        ProcessInstance instance = processService.startProcessDefinition(definitionKey, businessKey, map);
        //3.为当前节点设置任务候选人
        //3.1使用任务Service，根据流程实例查询到当前正在进行中的任务
        List<Task> taskList = processService.getTaskByInstanceId(instance.getId());
        List<String> auditorNames = null;
        //3.3使用任务Service，为当前任务设置候选人
        for (Task task : taskList) {
            auditorNames =  new ArrayList<>();
            //3.2根据当前任务的 key去 t definition_node节点表查询到所关联的审核候选人
            List<SysUser> auditors = definitionNodeService.selectAuditorsByNodeKey(task.getTaskDefinitionKey());
            for (SysUser auditor : auditors) {
                auditorNames.add(auditor.getUserName());
                Long userId = auditor.getUserId();
                processService.setTaskCandidateUser(task.getId(), String.valueOf(userId));
            }
        }
        //4.更新审核记录
        CarPackageAudit carPackageAudit1 = new CarPackageAudit();
        carPackageAudit1.setId(carPackageAudit.getId());
        //4.1将开始的流程实例id设置到审核对象中
        carPackageAudit1.setInstanceId(instance.getId());
        if (auditorNames != null){
            carPackageAudit1.setAuditors(JSON.toJSONString(auditorNames));
        }
        //4.2当前任务节点的候选人设置到审核对象的auditors字段中4.3更新审核记录
        carPackageAuditService.updateCarPackageAudit(carPackageAudit1);

    }
    @Override
    public void updateAuditStatus(Long id, Integer oldStatus, Integer newStatus) {
        serviceItemMapper.changeAuditStatus(id, oldStatus, newStatus);
    }

    @Override
    public void updateAuditingServiceItem(ServiceItem serviceItem) {
        ServiceItem oldServiceItem = this.selectServiceItemById(serviceItem.getId());
        if (!oldServiceItem.getAuditStatus().equals(ServiceItem.AUDITSTATUS_AUDITING)){
            throw new BusinessException("只有审核中的服务项才能在此修改");
        }
        serviceItem.setVersion(oldServiceItem.getVersion());
        serviceItemMapper.updateServiceItem(serviceItem);
    }

}
